﻿global using Devonline.Core;

namespace Devonline.Communication.Abstractions;

/// <summary>
/// 通讯器接口
/// 只提供异步方法是因为大多数面向通讯的方式都是异步的, 同步方法可以使用异步调用, 但异步方法同步化调用就比较容易引发问题
/// </summary>
/// <typeparam name="T">通讯器传输的数据类型</typeparam>
public interface ICommunicator<T>
{
    /// <summary>
    /// 运行状态
    /// </summary>
    public bool IsRunning { get; }
    /// <summary>
    /// 连接状态
    /// </summary>
    public bool IsConnected { get; }

    /// <summary>
    /// 初始化事件处理方法, 在通讯器初始化阶段(包括通过消息流的二次初始化)调用
    /// </summary>
    event EventHandler<ICommunicatorOptions>? Initial;
    /// <summary>
    /// 当通讯器连接或打开前执行的事件委托, 发生于每次发起连接/打开请求时, 以及断线重连/重新打开时
    /// </summary>
    event EventHandler? Connecting;
    /// <summary>
    /// 当通讯器成功连接或打开后执行的事件委托, 发生于每次发起连接/打开请求后, 以及断线重连/重新打开成功后
    /// </summary>
    event EventHandler? Connected;
    /// <summary>
    /// 通讯间隔监控触发时执行的事件处理委托方法
    /// </summary>
    event EventHandler? Monitor;
    /// <summary>
    /// 当通讯结束(包括连接终止/强制终止)时执行的事件委托
    /// </summary>
    event EventHandler? Abort;
    /// <summary>
    /// 收到来自通讯器消息时执行的事件处理委托方法
    /// </summary>
    event EventHandler<T>? Receive;
    /// <summary>
    /// 通讯出现错误时执行的事件处理委托方法
    /// </summary>
    event EventHandler<Exception>? Error;

    /// <summary>
    /// 启动通讯
    /// </summary>
    /// <returns></returns>
    Task StartAsync();
    /// <summary>
    /// 停止通讯
    /// </summary>
    /// <returns></returns>
    Task StopAsync();
    /// <summary>
    /// 暂停通讯
    /// </summary>
    void Pause();
    /// <summary>
    /// 继续通讯
    /// </summary>
    void Continue();
    /// <summary>
    /// 发送数据到通讯终端
    /// </summary>
    /// <returns></returns>
    Task SendAsync(T t);
}

/// <summary>
/// 以字符串作为通讯内容的通讯器
/// </summary>
public interface ICommunicator : ICommunicator<string> { }

/// <summary>
/// 以二进制数据流作为通讯内容的通讯器
/// </summary>
public interface IStreamCommunicator : ICommunicator<byte[]> { }